#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
代理模式 (Proxy Pattern) - Python实现详解

代理模式是一种结构设计模式，它为另一个对象提供一个替身或占位符以控制对这个对象的访问。
代理模式可以在不改变原始对象的情况下，提供额外的功能，如延迟加载、访问控制、缓存等。

与Java对比：
1. Python的装饰器提供了更简洁的代理实现方式
2. Python的__getattr__和__setattr__支持动态代理
3. Python的上下文管理器可以实现资源代理
4. Python的元类可以实现更高级的代理功能

作者: Assistant
日期: 2024
"""

import time
import threading
import weakref
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Callable, Union
from dataclasses import dataclass
from functools import wraps, lru_cache
from contextlib import contextmanager
import logging
import json
from collections import defaultdict
import hashlib


# ============================================================================
# 1. 传统代理模式实现
# ============================================================================

class Subject(ABC):
    """
    抽象主题
    定义了RealSubject和Proxy的共同接口
    """
    
    @abstractmethod
    def request(self) -> str:
        """处理请求"""
        pass


class RealSubject(Subject):
    """
    真实主题
    定义了代理所代表的真实对象
    """
    
    def __init__(self, name: str):
        self.name = name
        print(f"创建真实主题: {name}")
    
    def request(self) -> str:
        """处理请求"""
        print(f"真实主题 {self.name} 正在处理请求")
        time.sleep(0.1)  # 模拟处理时间
        return f"真实主题 {self.name} 的响应"
    
    def expensive_operation(self) -> str:
        """昂贵的操作"""
        print(f"真实主题 {self.name} 正在执行昂贵操作")
        time.sleep(0.5)  # 模拟昂贵操作
        return f"真实主题 {self.name} 的昂贵操作结果"


class Proxy(Subject):
    """
    代理
    保存一个引用使得代理可以访问实体，并提供一个与Subject的接口相同的接口
    """
    
    def __init__(self, real_subject: RealSubject):
        self._real_subject = real_subject
        self._access_count = 0
    
    def request(self) -> str:
        """代理的请求处理"""
        # 前置处理
        self._access_count += 1
        print(f"代理: 访问次数 {self._access_count}")
        
        # 访问控制
        if self._access_count > 5:
            return "代理: 访问次数超限，拒绝请求"
        
        # 委托给真实主题
        result = self._real_subject.request()
        
        # 后置处理
        print("代理: 请求处理完成")
        
        return result
    
    def get_access_count(self) -> int:
        """获取访问次数"""
        return self._access_count


# ============================================================================
# 2. 虚拟代理实现（延迟加载）
# ============================================================================

class ExpensiveResource:
    """
    昂贵的资源
    模拟需要大量时间或内存来创建的对象
    """
    
    def __init__(self, resource_id: str):
        self.resource_id = resource_id
        print(f"正在加载昂贵资源: {resource_id}...")
        time.sleep(1)  # 模拟加载时间
        self.data = f"资源 {resource_id} 的数据" * 1000  # 模拟大量数据
        print(f"昂贵资源 {resource_id} 加载完成")
    
    def get_data(self) -> str:
        """获取资源数据"""
        return f"来自资源 {self.resource_id} 的数据 (大小: {len(self.data)} 字符)"
    
    def process_data(self, input_data: str) -> str:
        """处理数据"""
        print(f"资源 {self.resource_id} 正在处理数据: {input_data}")
        return f"处理结果: {input_data.upper()}"


class VirtualProxy:
    """
    虚拟代理
    实现延迟加载，只有在真正需要时才创建昂贵的资源
    """
    
    def __init__(self, resource_id: str):
        self._resource_id = resource_id
        self._real_resource: Optional[ExpensiveResource] = None
        self._is_loading = False
    
    def _get_real_resource(self) -> ExpensiveResource:
        """获取真实资源，如果不存在则创建"""
        if self._real_resource is None and not self._is_loading:
            self._is_loading = True
            print(f"虚拟代理: 首次访问，开始加载资源 {self._resource_id}")
            self._real_resource = ExpensiveResource(self._resource_id)
            self._is_loading = False
        
        return self._real_resource
    
    def get_data(self) -> str:
        """获取数据"""
        if self._real_resource is None:
            print(f"虚拟代理: 资源 {self._resource_id} 尚未加载")
        
        real_resource = self._get_real_resource()
        return real_resource.get_data()
    
    def process_data(self, input_data: str) -> str:
        """处理数据"""
        real_resource = self._get_real_resource()
        return real_resource.process_data(input_data)
    
    def is_loaded(self) -> bool:
        """检查资源是否已加载"""
        return self._real_resource is not None


# ============================================================================
# 3. 保护代理实现（访问控制）
# ============================================================================

class User:
    """
    用户类
    """
    
    def __init__(self, username: str, role: str):
        self.username = username
        self.role = role
    
    def __str__(self) -> str:
        return f"User({self.username}, {self.role})"


class SecureDocument:
    """
    安全文档
    需要权限控制的文档
    """
    
    def __init__(self, title: str, content: str, classification: str):
        self.title = title
        self.content = content
        self.classification = classification  # public, internal, confidential, secret
        self.access_log: List[str] = []
    
    def read(self, user: User) -> str:
        """读取文档"""
        log_entry = f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {user.username} 读取了文档"
        self.access_log.append(log_entry)
        return f"文档标题: {self.title}\n内容: {self.content}"
    
    def write(self, user: User, new_content: str) -> bool:
        """写入文档"""
        log_entry = f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {user.username} 修改了文档"
        self.access_log.append(log_entry)
        self.content = new_content
        return True
    
    def delete(self, user: User) -> bool:
        """删除文档"""
        log_entry = f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {user.username} 删除了文档"
        self.access_log.append(log_entry)
        return True
    
    def get_access_log(self) -> List[str]:
        """获取访问日志"""
        return self.access_log.copy()


class DocumentProxy:
    """
    文档代理
    实现访问控制和权限检查
    """
    
    # 权限级别映射
    PERMISSION_LEVELS = {
        'public': 0,
        'internal': 1,
        'confidential': 2,
        'secret': 3
    }
    
    # 角色权限映射
    ROLE_PERMISSIONS = {
        'guest': 0,
        'employee': 1,
        'manager': 2,
        'admin': 3
    }
    
    def __init__(self, document: SecureDocument):
        self._document = document
        self._failed_attempts: Dict[str, int] = defaultdict(int)
        self._blocked_users: Set[str] = set()
    
    def _check_permission(self, user: User, required_level: int) -> bool:
        """检查用户权限"""
        if user.username in self._blocked_users:
            print(f"用户 {user.username} 已被阻止访问")
            return False
        
        user_level = self.ROLE_PERMISSIONS.get(user.role, 0)
        return user_level >= required_level
    
    def _log_failed_attempt(self, user: User, action: str) -> None:
        """记录失败尝试"""
        self._failed_attempts[user.username] += 1
        print(f"用户 {user.username} 尝试 {action} 失败 (第{self._failed_attempts[user.username]}次)")
        
        # 3次失败后阻止用户
        if self._failed_attempts[user.username] >= 3:
            self._blocked_users.add(user.username)
            print(f"用户 {user.username} 因多次失败尝试被阻止")
    
    def read(self, user: User) -> Optional[str]:
        """读取文档"""
        required_level = self.PERMISSION_LEVELS.get(self._document.classification, 0)
        
        if not self._check_permission(user, required_level):
            self._log_failed_attempt(user, "读取")
            return None
        
        print(f"代理: 允许用户 {user.username} 读取文档")
        return self._document.read(user)
    
    def write(self, user: User, new_content: str) -> bool:
        """写入文档"""
        # 写入需要更高权限
        required_level = self.PERMISSION_LEVELS.get(self._document.classification, 0) + 1
        
        if not self._check_permission(user, required_level):
            self._log_failed_attempt(user, "写入")
            return False
        
        print(f"代理: 允许用户 {user.username} 写入文档")
        return self._document.write(user, new_content)
    
    def delete(self, user: User) -> bool:
        """删除文档"""
        # 删除需要最高权限
        if not self._check_permission(user, 3):
            self._log_failed_attempt(user, "删除")
            return False
        
        print(f"代理: 允许用户 {user.username} 删除文档")
        return self._document.delete(user)
    
    def get_access_log(self, user: User) -> Optional[List[str]]:
        """获取访问日志"""
        if not self._check_permission(user, 2):  # 需要管理员权限
            self._log_failed_attempt(user, "查看日志")
            return None
        
        return self._document.get_access_log()
    
    def unblock_user(self, admin_user: User, username: str) -> bool:
        """解除用户阻止"""
        if not self._check_permission(admin_user, 3):
            return False
        
        if username in self._blocked_users:
            self._blocked_users.remove(username)
            self._failed_attempts[username] = 0
            print(f"管理员 {admin_user.username} 解除了用户 {username} 的阻止")
            return True
        
        return False


# ============================================================================
# 4. 缓存代理实现
# ============================================================================

class DataService:
    """
    数据服务
    模拟需要缓存的数据服务
    """
    
    def __init__(self, name: str):
        self.name = name
        self.call_count = 0
    
    def get_data(self, key: str) -> str:
        """获取数据"""
        self.call_count += 1
        print(f"数据服务 {self.name}: 正在获取数据 '{key}' (第{self.call_count}次调用)")
        time.sleep(0.2)  # 模拟网络延迟
        return f"数据服务 {self.name} 返回的数据: {key.upper()}"
    
    def update_data(self, key: str, value: str) -> bool:
        """更新数据"""
        self.call_count += 1
        print(f"数据服务 {self.name}: 正在更新数据 '{key}' = '{value}' (第{self.call_count}次调用)")
        time.sleep(0.1)  # 模拟网络延迟
        return True
    
    def get_call_count(self) -> int:
        """获取调用次数"""
        return self.call_count


class CacheProxy:
    """
    缓存代理
    为数据服务提供缓存功能
    """
    
    def __init__(self, data_service: DataService, cache_ttl: int = 60):
        self._data_service = data_service
        self._cache: Dict[str, Tuple[str, float]] = {}  # key -> (value, timestamp)
        self._cache_ttl = cache_ttl  # 缓存生存时间（秒）
        self._cache_hits = 0
        self._cache_misses = 0
        self._lock = threading.Lock()
    
    def _is_cache_valid(self, timestamp: float) -> bool:
        """检查缓存是否有效"""
        return time.time() - timestamp < self._cache_ttl
    
    def _clean_expired_cache(self) -> None:
        """清理过期缓存"""
        current_time = time.time()
        expired_keys = [
            key for key, (_, timestamp) in self._cache.items()
            if current_time - timestamp >= self._cache_ttl
        ]
        
        for key in expired_keys:
            del self._cache[key]
            print(f"缓存代理: 清理过期缓存 '{key}'")
    
    def get_data(self, key: str) -> str:
        """获取数据（带缓存）"""
        with self._lock:
            # 清理过期缓存
            self._clean_expired_cache()
            
            # 检查缓存
            if key in self._cache:
                value, timestamp = self._cache[key]
                if self._is_cache_valid(timestamp):
                    self._cache_hits += 1
                    print(f"缓存代理: 缓存命中 '{key}'")
                    return value
                else:
                    # 缓存过期，删除
                    del self._cache[key]
            
            # 缓存未命中，从数据服务获取
            self._cache_misses += 1
            print(f"缓存代理: 缓存未命中 '{key}'，从数据服务获取")
            value = self._data_service.get_data(key)
            
            # 存入缓存
            self._cache[key] = (value, time.time())
            print(f"缓存代理: 将数据 '{key}' 存入缓存")
            
            return value
    
    def update_data(self, key: str, value: str) -> bool:
        """更新数据（清除相关缓存）"""
        with self._lock:
            # 更新数据服务
            result = self._data_service.update_data(key, value)
            
            if result:
                # 清除相关缓存
                if key in self._cache:
                    del self._cache[key]
                    print(f"缓存代理: 清除缓存 '{key}'")
            
            return result
    
    def get_cache_stats(self) -> Dict[str, Any]:
        """获取缓存统计"""
        total_requests = self._cache_hits + self._cache_misses
        hit_rate = (self._cache_hits / total_requests * 100) if total_requests > 0 else 0
        
        return {
            "缓存命中次数": self._cache_hits,
            "缓存未命中次数": self._cache_misses,
            "总请求次数": total_requests,
            "缓存命中率": f"{hit_rate:.1f}%",
            "当前缓存大小": len(self._cache),
            "数据服务调用次数": self._data_service.get_call_count()
        }
    
    def clear_cache(self) -> None:
        """清空缓存"""
        with self._lock:
            cache_size = len(self._cache)
            self._cache.clear()
            print(f"缓存代理: 清空缓存，删除了 {cache_size} 个条目")


# ============================================================================
# 5. 智能引用代理实现
# ============================================================================

class ManagedResource:
    """
    被管理的资源
    """
    
    def __init__(self, resource_id: str):
        self.resource_id = resource_id
        self.data = f"资源 {resource_id} 的数据"
        print(f"创建资源: {resource_id}")
    
    def process(self, input_data: str) -> str:
        """处理数据"""
        print(f"资源 {self.resource_id} 正在处理: {input_data}")
        return f"处理结果: {input_data} -> {self.resource_id}"
    
    def cleanup(self) -> None:
        """清理资源"""
        print(f"清理资源: {self.resource_id}")
    
    def __del__(self):
        print(f"资源 {self.resource_id} 被销毁")


class SmartReferenceProxy:
    """
    智能引用代理
    提供引用计数和自动资源管理
    """
    
    # 类级别的资源池和引用计数
    _resource_pool: Dict[str, ManagedResource] = {}
    _reference_counts: Dict[str, int] = defaultdict(int)
    _lock = threading.Lock()
    
    def __init__(self, resource_id: str):
        self._resource_id = resource_id
        
        with SmartReferenceProxy._lock:
            # 增加引用计数
            SmartReferenceProxy._reference_counts[resource_id] += 1
            
            # 如果资源不存在，创建它
            if resource_id not in SmartReferenceProxy._resource_pool:
                SmartReferenceProxy._resource_pool[resource_id] = ManagedResource(resource_id)
                print(f"智能代理: 创建新资源 {resource_id}")
            else:
                print(f"智能代理: 复用现有资源 {resource_id}")
            
            print(f"智能代理: 资源 {resource_id} 引用计数: {SmartReferenceProxy._reference_counts[resource_id]}")
    
    def process(self, input_data: str) -> str:
        """处理数据"""
        resource = SmartReferenceProxy._resource_pool.get(self._resource_id)
        if resource:
            return resource.process(input_data)
        else:
            raise RuntimeError(f"资源 {self._resource_id} 不可用")
    
    def get_reference_count(self) -> int:
        """获取引用计数"""
        return SmartReferenceProxy._reference_counts[self._resource_id]
    
    def __del__(self):
        """析构函数，减少引用计数"""
        with SmartReferenceProxy._lock:
            if self._resource_id in SmartReferenceProxy._reference_counts:
                SmartReferenceProxy._reference_counts[self._resource_id] -= 1
                print(f"智能代理: 资源 {self._resource_id} 引用计数: {SmartReferenceProxy._reference_counts[self._resource_id]}")
                
                # 如果引用计数为0，清理资源
                if SmartReferenceProxy._reference_counts[self._resource_id] <= 0:
                    resource = SmartReferenceProxy._resource_pool.pop(self._resource_id, None)
                    if resource:
                        resource.cleanup()
                        print(f"智能代理: 清理资源 {self._resource_id}")
                    
                    del SmartReferenceProxy._reference_counts[self._resource_id]
    
    @classmethod
    def get_resource_stats(cls) -> Dict[str, Any]:
        """获取资源统计"""
        with cls._lock:
            return {
                "活跃资源数": len(cls._resource_pool),
                "资源列表": list(cls._resource_pool.keys()),
                "引用计数": dict(cls._reference_counts)
            }
    
    @classmethod
    def force_cleanup_all(cls) -> None:
        """强制清理所有资源"""
        with cls._lock:
            for resource in cls._resource_pool.values():
                resource.cleanup()
            
            cls._resource_pool.clear()
            cls._reference_counts.clear()
            print("智能代理: 强制清理所有资源")


# ============================================================================
# 6. 装饰器代理实现
# ============================================================================

def logging_proxy(func: Callable) -> Callable:
    """
    日志代理装饰器
    为函数调用添加日志记录
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 前置日志
        print(f"日志代理: 调用函数 {func.__name__}")
        print(f"日志代理: 参数 args={args}, kwargs={kwargs}")
        
        start_time = time.time()
        
        try:
            # 调用原函数
            result = func(*args, **kwargs)
            
            # 成功日志
            end_time = time.time()
            print(f"日志代理: 函数 {func.__name__} 执行成功，耗时 {end_time - start_time:.3f}秒")
            print(f"日志代理: 返回值 {result}")
            
            return result
        
        except Exception as e:
            # 错误日志
            end_time = time.time()
            print(f"日志代理: 函数 {func.__name__} 执行失败，耗时 {end_time - start_time:.3f}秒")
            print(f"日志代理: 错误信息 {e}")
            raise
    
    return wrapper


def retry_proxy(max_retries: int = 3, delay: float = 1.0):
    """
    重试代理装饰器
    为函数调用添加重试机制
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs):
            last_exception = None
            
            for attempt in range(max_retries + 1):
                try:
                    if attempt > 0:
                        print(f"重试代理: 第 {attempt} 次重试函数 {func.__name__}")
                        time.sleep(delay)
                    
                    result = func(*args, **kwargs)
                    
                    if attempt > 0:
                        print(f"重试代理: 函数 {func.__name__} 重试成功")
                    
                    return result
                
                except Exception as e:
                    last_exception = e
                    print(f"重试代理: 函数 {func.__name__} 第 {attempt + 1} 次尝试失败: {e}")
            
            print(f"重试代理: 函数 {func.__name__} 所有重试都失败")
            raise last_exception
        
        return wrapper
    
    return decorator


def cache_proxy(ttl: int = 300):
    """
    缓存代理装饰器
    为函数调用添加缓存功能
    """
    def decorator(func: Callable) -> Callable:
        cache = {}
        cache_times = {}
        
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 生成缓存键
            key = str(args) + str(sorted(kwargs.items()))
            key_hash = hashlib.md5(key.encode()).hexdigest()
            
            current_time = time.time()
            
            # 检查缓存
            if key_hash in cache and key_hash in cache_times:
                if current_time - cache_times[key_hash] < ttl:
                    print(f"缓存代理: 函数 {func.__name__} 缓存命中")
                    return cache[key_hash]
                else:
                    # 缓存过期
                    del cache[key_hash]
                    del cache_times[key_hash]
                    print(f"缓存代理: 函数 {func.__name__} 缓存过期")
            
            # 调用原函数
            print(f"缓存代理: 函数 {func.__name__} 缓存未命中，执行函数")
            result = func(*args, **kwargs)
            
            # 存入缓存
            cache[key_hash] = result
            cache_times[key_hash] = current_time
            print(f"缓存代理: 函数 {func.__name__} 结果已缓存")
            
            return result
        
        # 添加缓存管理方法
        wrapper.clear_cache = lambda: cache.clear() or cache_times.clear()
        wrapper.get_cache_size = lambda: len(cache)
        
        return wrapper
    
    return decorator


# ============================================================================
# 7. 动态代理实现
# ============================================================================

class DynamicProxy:
    """
    动态代理
    可以代理任意对象，并添加横切关注点
    """
    
    def __init__(self, target: Any, interceptors: List[Callable] = None):
        self._target = target
        self._interceptors = interceptors or []
        self._call_log: List[Dict[str, Any]] = []
    
    def add_interceptor(self, interceptor: Callable) -> None:
        """添加拦截器"""
        self._interceptors.append(interceptor)
    
    def __getattr__(self, name: str) -> Any:
        """动态属性访问"""
        target_attr = getattr(self._target, name)
        
        if callable(target_attr):
            # 如果是方法，返回代理方法
            def proxy_method(*args, **kwargs):
                # 记录调用信息
                call_info = {
                    'method': name,
                    'args': args,
                    'kwargs': kwargs,
                    'timestamp': time.time()
                }
                
                # 执行前置拦截器
                for interceptor in self._interceptors:
                    try:
                        interceptor('before', name, args, kwargs)
                    except Exception as e:
                        print(f"动态代理: 前置拦截器错误: {e}")
                
                try:
                    # 调用目标方法
                    result = target_attr(*args, **kwargs)
                    call_info['result'] = result
                    call_info['success'] = True
                    
                    # 执行后置拦截器
                    for interceptor in self._interceptors:
                        try:
                            interceptor('after', name, args, kwargs, result)
                        except Exception as e:
                            print(f"动态代理: 后置拦截器错误: {e}")
                    
                    return result
                
                except Exception as e:
                    call_info['error'] = str(e)
                    call_info['success'] = False
                    
                    # 执行异常拦截器
                    for interceptor in self._interceptors:
                        try:
                            interceptor('error', name, args, kwargs, e)
                        except Exception as ie:
                            print(f"动态代理: 异常拦截器错误: {ie}")
                    
                    raise
                
                finally:
                    self._call_log.append(call_info)
            
            return proxy_method
        else:
            # 如果是属性，直接返回
            return target_attr
    
    def get_call_log(self) -> List[Dict[str, Any]]:
        """获取调用日志"""
        return self._call_log.copy()
    
    def clear_call_log(self) -> None:
        """清空调用日志"""
        self._call_log.clear()


def performance_interceptor(phase: str, method: str, args: tuple, kwargs: dict, *extra) -> None:
    """
    性能监控拦截器
    """
    if phase == 'before':
        print(f"性能监控: 开始执行方法 {method}")
    elif phase == 'after':
        print(f"性能监控: 方法 {method} 执行完成")
    elif phase == 'error':
        print(f"性能监控: 方法 {method} 执行出错")


def security_interceptor(phase: str, method: str, args: tuple, kwargs: dict, *extra) -> None:
    """
    安全检查拦截器
    """
    if phase == 'before':
        print(f"安全检查: 验证方法 {method} 的访问权限")
        # 这里可以添加实际的安全检查逻辑
    elif phase == 'error':
        print(f"安全检查: 方法 {method} 执行出错，记录安全日志")


# ============================================================================
# 8. 演示函数
# ============================================================================

def demonstrate_basic_proxy():
    """
    演示基本代理模式
    """
    print("\n=== 基本代理模式演示 ===")
    
    # 创建真实主题和代理
    real_subject = RealSubject("服务A")
    proxy = Proxy(real_subject)
    
    print("\n=== 通过代理访问服务 ===")
    
    # 多次访问，观察代理的访问控制
    for i in range(7):
        print(f"\n--- 第 {i+1} 次访问 ---")
        result = proxy.request()
        print(f"结果: {result}")
    
    print(f"\n总访问次数: {proxy.get_access_count()}")


def demonstrate_virtual_proxy():
    """
    演示虚拟代理（延迟加载）
    """
    print("\n=== 虚拟代理演示 ===")
    
    # 创建虚拟代理
    print("\n=== 创建虚拟代理 ===")
    proxy1 = VirtualProxy("资源1")
    proxy2 = VirtualProxy("资源2")
    
    print(f"代理1是否已加载: {proxy1.is_loaded()}")
    print(f"代理2是否已加载: {proxy2.is_loaded()}")
    
    # 首次访问，触发延迟加载
    print("\n=== 首次访问代理1 ===")
    data1 = proxy1.get_data()
    print(f"获取的数据: {data1}")
    print(f"代理1是否已加载: {proxy1.is_loaded()}")
    
    # 再次访问，不会重新加载
    print("\n=== 再次访问代理1 ===")
    result1 = proxy1.process_data("测试数据")
    print(f"处理结果: {result1}")
    
    # 访问代理2
    print("\n=== 访问代理2 ===")
    data2 = proxy2.get_data()
    print(f"获取的数据: {data2}")


def demonstrate_protection_proxy():
    """
    演示保护代理（访问控制）
    """
    print("\n=== 保护代理演示 ===")
    
    # 创建文档和代理
    document = SecureDocument("机密文档", "这是机密内容", "confidential")
    proxy = DocumentProxy(document)
    
    # 创建不同权限的用户
    guest = User("guest_user", "guest")
    employee = User("employee_user", "employee")
    manager = User("manager_user", "manager")
    admin = User("admin_user", "admin")
    
    users = [guest, employee, manager, admin]
    
    print("\n=== 测试读取权限 ===")
    for user in users:
        print(f"\n--- {user} 尝试读取文档 ---")
        content = proxy.read(user)
        if content:
            print(f"读取成功: {content[:50]}...")
        else:
            print("读取失败")
    
    print("\n=== 测试写入权限 ===")
    for user in users:
        print(f"\n--- {user} 尝试写入文档 ---")
        success = proxy.write(user, f"由 {user.username} 修改的内容")
        print(f"写入{'成功' if success else '失败'}")
    
    print("\n=== 测试删除权限 ===")
    for user in users:
        print(f"\n--- {user} 尝试删除文档 ---")
        success = proxy.delete(user)
        print(f"删除{'成功' if success else '失败'}")
    
    # 测试多次失败尝试
    print("\n=== 测试多次失败尝试 ===")
    for i in range(4):
        print(f"\n--- guest用户第 {i+1} 次尝试写入 ---")
        proxy.write(guest, "非法内容")
    
    # 管理员解除阻止
    print("\n=== 管理员解除用户阻止 ===")
    proxy.unblock_user(admin, "guest_user")


def demonstrate_cache_proxy():
    """
    演示缓存代理
    """
    print("\n=== 缓存代理演示 ===")
    
    # 创建数据服务和缓存代理
    data_service = DataService("API服务")
    cache_proxy = CacheProxy(data_service, cache_ttl=5)  # 5秒缓存
    
    print("\n=== 测试缓存功能 ===")
    
    # 首次访问
    print("\n--- 首次访问 ---")
    result1 = cache_proxy.get_data("user123")
    print(f"结果: {result1}")
    
    # 再次访问相同数据（应该命中缓存）
    print("\n--- 再次访问相同数据 ---")
    result2 = cache_proxy.get_data("user123")
    print(f"结果: {result2}")
    
    # 访问不同数据
    print("\n--- 访问不同数据 ---")
    result3 = cache_proxy.get_data("user456")
    print(f"结果: {result3}")
    
    # 显示缓存统计
    print("\n--- 缓存统计 ---")
    stats = cache_proxy.get_cache_stats()
    for key, value in stats.items():
        print(f"{key}: {value}")
    
    # 更新数据（会清除缓存）
    print("\n--- 更新数据 ---")
    cache_proxy.update_data("user123", "新数据")
    
    # 再次访问更新的数据
    print("\n--- 访问更新后的数据 ---")
    result4 = cache_proxy.get_data("user123")
    print(f"结果: {result4}")
    
    # 等待缓存过期
    print("\n--- 等待缓存过期 ---")
    time.sleep(6)
    result5 = cache_proxy.get_data("user456")
    print(f"结果: {result5}")
    
    # 最终统计
    print("\n--- 最终缓存统计 ---")
    stats = cache_proxy.get_cache_stats()
    for key, value in stats.items():
        print(f"{key}: {value}")


def demonstrate_smart_reference_proxy():
    """
    演示智能引用代理
    """
    print("\n=== 智能引用代理演示 ===")
    
    print("\n=== 创建多个代理引用 ===")
    
    # 创建多个引用同一资源的代理
    proxy1 = SmartReferenceProxy("共享资源A")
    proxy2 = SmartReferenceProxy("共享资源A")  # 应该复用资源
    proxy3 = SmartReferenceProxy("共享资源B")
    
    # 显示资源统计
    print("\n--- 当前资源统计 ---")
    stats = SmartReferenceProxy.get_resource_stats()
    for key, value in stats.items():
        print(f"{key}: {value}")
    
    # 使用代理
    print("\n=== 使用代理处理数据 ===")
    result1 = proxy1.process("数据1")
    result2 = proxy2.process("数据2")
    result3 = proxy3.process("数据3")
    
    print(f"代理1结果: {result1}")
    print(f"代理2结果: {result2}")
    print(f"代理3结果: {result3}")
    
    # 删除一些代理
    print("\n=== 删除代理引用 ===")
    print(f"删除proxy1前，资源A引用计数: {proxy1.get_reference_count()}")
    del proxy1
    
    print(f"删除proxy1后，资源A引用计数: {proxy2.get_reference_count()}")
    
    # 显示资源统计
    print("\n--- 删除后资源统计 ---")
    stats = SmartReferenceProxy.get_resource_stats()
    for key, value in stats.items():
        print(f"{key}: {value}")
    
    # 删除所有引用
    print("\n=== 删除所有引用 ===")
    del proxy2, proxy3
    
    # 显示最终统计
    print("\n--- 最终资源统计 ---")
    stats = SmartReferenceProxy.get_resource_stats()
    for key, value in stats.items():
        print(f"{key}: {value}")


def demonstrate_decorator_proxy():
    """
    演示装饰器代理
    """
    print("\n=== 装饰器代理演示 ===")
    
    # 定义测试函数
    @logging_proxy
    @retry_proxy(max_retries=2, delay=0.5)
    @cache_proxy(ttl=10)
    def calculate_fibonacci(n: int) -> int:
        """计算斐波那契数列"""
        if n < 0:
            raise ValueError("n必须为非负数")
        if n <= 1:
            return n
        
        # 模拟计算时间
        time.sleep(0.1)
        return calculate_fibonacci(n-1) + calculate_fibonacci(n-2)
    
    @logging_proxy
    def unreliable_function(success_rate: float = 0.3) -> str:
        """不可靠的函数，用于测试重试机制"""
        import random
        if random.random() < success_rate:
            return "成功执行"
        else:
            raise RuntimeError("随机失败")
    
    print("\n=== 测试缓存装饰器 ===")
    
    # 首次计算
    print("\n--- 首次计算 fibonacci(5) ---")
    result1 = calculate_fibonacci(5)
    print(f"结果: {result1}")
    
    # 再次计算（应该使用缓存）
    print("\n--- 再次计算 fibonacci(5) ---")
    result2 = calculate_fibonacci(5)
    print(f"结果: {result2}")
    
    print(f"\n缓存大小: {calculate_fibonacci.get_cache_size()}")
    
    print("\n=== 测试重试装饰器 ===")
    
    # 测试重试机制
    for i in range(3):
        print(f"\n--- 第 {i+1} 次尝试不可靠函数 ---")
        try:
            result = unreliable_function(0.2)  # 20%成功率
            print(f"最终结果: {result}")
            break
        except Exception as e:
            print(f"最终失败: {e}")


def demonstrate_dynamic_proxy():
    """
    演示动态代理
    """
    print("\n=== 动态代理演示 ===")
    
    # 创建目标对象
    class Calculator:
        def add(self, a: int, b: int) -> int:
            return a + b
        
        def divide(self, a: int, b: int) -> float:
            if b == 0:
                raise ValueError("除数不能为零")
            return a / b
        
        def multiply(self, a: int, b: int) -> int:
            return a * b
    
    calculator = Calculator()
    
    # 创建动态代理
    proxy = DynamicProxy(calculator, [performance_interceptor, security_interceptor])
    
    print("\n=== 通过动态代理调用方法 ===")
    
    # 正常调用
    print("\n--- 正常调用 ---")
    result1 = proxy.add(10, 5)
    print(f"10 + 5 = {result1}")
    
    result2 = proxy.multiply(3, 4)
    print(f"3 * 4 = {result2}")
    
    # 异常调用
    print("\n--- 异常调用 ---")
    try:
        result3 = proxy.divide(10, 0)
    except ValueError as e:
        print(f"捕获异常: {e}")
    
    # 显示调用日志
    print("\n--- 调用日志 ---")
    call_log = proxy.get_call_log()
    for i, log_entry in enumerate(call_log, 1):
        print(f"调用 {i}: {log_entry['method']} - 成功: {log_entry.get('success', False)}")
        if 'error' in log_entry:
            print(f"  错误: {log_entry['error']}")


def demonstrate_performance_comparison():
    """
    演示性能对比
    """
    print("\n=== 性能对比演示 ===")
    
    # 创建测试数据
    num_requests = 100
    
    print(f"\n=== 测试 {num_requests} 次请求的性能 ===")
    
    # 不使用代理的直接访问
    print("\n--- 直接访问数据服务 ---")
    data_service = DataService("直接服务")
    
    start_time = time.time()
    for i in range(num_requests):
        key = f"key{i % 10}"  # 10个不同的键，会有重复
        data_service.get_data(key)
    direct_time = time.time() - start_time
    
    print(f"直接访问总时间: {direct_time:.3f}秒")
    print(f"平均每次请求: {direct_time/num_requests*1000:.3f}毫秒")
    print(f"服务调用次数: {data_service.get_call_count()}")
    
    # 使用缓存代理
    print("\n--- 使用缓存代理 ---")
    cached_service = DataService("缓存服务")
    cache_proxy = CacheProxy(cached_service, cache_ttl=60)
    
    start_time = time.time()
    for i in range(num_requests):
        key = f"key{i % 10}"  # 相同的键模式
        cache_proxy.get_data(key)
    cached_time = time.time() - start_time
    
    print(f"缓存代理总时间: {cached_time:.3f}秒")
    print(f"平均每次请求: {cached_time/num_requests*1000:.3f}毫秒")
    print(f"服务调用次数: {cached_service.get_call_count()}")
    
    # 性能对比
    print("\n=== 性能对比结果 ===")
    improvement = (direct_time - cached_time) / direct_time * 100
    print(f"时间改进: {improvement:.1f}%")
    print(f"调用次数减少: {(data_service.get_call_count() - cached_service.get_call_count()) / data_service.get_call_count() * 100:.1f}%")
    
    # 缓存统计
    stats = cache_proxy.get_cache_stats()
    print(f"缓存命中率: {stats['缓存命中率']}")


def demonstrate_java_comparison():
    """
    演示与Java的对比
    """
    print("\n=== Python vs Java 代理模式对比 ===")
    
    print("\n=== Java实现特点 ===")
    print("""
    Java代理模式的实现:
    
    // Java接口
    public interface Subject {
        String request();
    }
    
    // Java真实主题
    public class RealSubject implements Subject {
        @Override
        public String request() {
            return "RealSubject response";
        }
    }
    
    // Java代理
    public class Proxy implements Subject {
        private RealSubject realSubject;
        
        public Proxy(RealSubject realSubject) {
            this.realSubject = realSubject;
        }
        
        @Override
        public String request() {
            // 前置处理
            System.out.println("Proxy: pre-processing");
            
            // 委托给真实主题
            String result = realSubject.request();
            
            // 后置处理
            System.out.println("Proxy: post-processing");
            
            return result;
        }
    }
    
    // Java动态代理
    Object proxy = Proxy.newProxyInstance(
        target.getClass().getClassLoader(),
        target.getClass().getInterfaces(),
        new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) {
                // 代理逻辑
                return method.invoke(target, args);
            }
        }
    );
    """)
    
    print("\n=== Python实现优势 ===")
    print("""
    Python代理模式的优势:
    
    1. 装饰器支持:
       - @decorator语法提供简洁的代理实现
       - 可以轻松组合多个代理功能
    
    2. 动态特性:
       - __getattr__和__setattr__支持动态代理
       - 不需要预定义接口
    
    3. 上下文管理器:
       - with语句支持资源代理
       - 自动资源管理
    
    4. 元类编程:
       - 可以在类级别实现代理
       - 更高级的代理功能
    
    5. 弱引用支持:
       - weakref模块支持智能引用代理
       - 自动内存管理
    """)
    
    print("\n=== 实际应用场景对比 ===")
    print("""
    应用场景对比:
    
    Java适合:
    - 企业级应用的AOP切面编程
    - Spring框架的代理机制
    - 大型系统的服务代理
    
    Python适合:
    - Web框架的中间件
    - 数据库连接池代理
    - API调用的缓存和重试
    - 资源访问控制
    - 性能监控和日志记录
    """)


def main():
    """
    主函数 - 演示所有代理模式实现
    """
    print("代理模式 (Proxy Pattern) - Python实现演示")
    print("=" * 60)
    
    # 演示基本代理模式
    demonstrate_basic_proxy()
    
    # 演示虚拟代理
    demonstrate_virtual_proxy()
    
    # 演示保护代理
    demonstrate_protection_proxy()
    
    # 演示缓存代理
    demonstrate_cache_proxy()
    
    # 演示智能引用代理
    demonstrate_smart_reference_proxy()
    
    # 演示装饰器代理
    demonstrate_decorator_proxy()
    
    # 演示动态代理
    demonstrate_dynamic_proxy()
    
    # 演示性能对比
    demonstrate_performance_comparison()
    
    # 演示Java对比
    demonstrate_java_comparison()
    
    print("\n=== 总结 ===")
    print("""
    代理模式的核心思想:
    1. 为其他对象提供一种代理以控制对这个对象的访问
    2. 在不改变原始对象的情况下提供额外功能
    3. 支持延迟加载、访问控制、缓存等功能
    
    Python实现的特点:
    1. 装饰器提供简洁的代理实现
    2. 动态特性支持灵活的代理创建
    3. 上下文管理器支持资源代理
    4. 弱引用支持智能引用代理
    
    适用场景:
    - 延迟加载昂贵资源
    - 访问控制和权限检查
    - 缓存和性能优化
    - 日志记录和监控
    - 资源管理和引用计数
    """)


if __name__ == "__main__":
    main()